package golib

/**
 * @apiDefine hasToken
 * @apiHeader {string} tenantId 租户id
 * @apiHeader {string} token 用户token

 * @apiSuccess {number} data.code 返回状态码:1=成功,其他=失败
 * @apiSuccess {string} data.msg 返回中文提示信息
 * @apiSuccess {json} data.data 数据
 */

/**
 * @apiDefine noToken
 * @apiHeader {string} tenantId 租户id

 * @apiSuccess {number} data.code 返回状态码:1=成功,其他=失败
 * @apiSuccess {string} data.msg 返回中文提示信息
 * @apiSuccess {json} data.data 数据
 */
import (
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"
)

func FormatData(msg string, data interface{}, status bool) map[string]interface{} {
	if status {
		return map[string]interface{}{"code": 1, "message": msg, "data": data}
	} else {
		return map[string]interface{}{"code": 0, "message": msg, "data": data}
	}
}

func GetUrl(url string) string {
	res, _ := http.Get(url)
	defer res.Body.Close()
	content, _ := ioutil.ReadAll(res.Body)
	return string(content)
}

func PostUrl(url string, data string) string {
	res, err := http.Post(url, "application/json", strings.NewReader(data))
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	content, _ := ioutil.ReadAll(res.Body)
	return string(content)
}

//Println 打印信息
func Println(msg ...interface{}) {
	fmt.Println(msg...)
}

//FileExists 判断文件是否存在
func FileExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

//转整型
func Int64(str interface{}) int64 {
	switch str.(type) {
	case string:
		var s string
		s, _ = str.(string)
		i, _ := strconv.ParseInt(s, 10, 64)
		return i
	case int:
		var i int
		i, _ = str.(int)
		return int64(i)
	case int32:
		var i int32
		i, _ = str.(int32)
		return int64(i)
	case float32:
		var i int64
		i, _ = str.(int64)
		return int64(i)
	case float64:
		var i float64
		i, _ = str.(float64)
		return int64(i)
	default:
		return str.(int64)
	}
}

//转浮点型
func Float64(str interface{}) float64 {
	switch str.(type) {
	case string:
		var s string
		s, _ = str.(string)
		i, _ := strconv.ParseFloat(s, 64)
		return i
	case int:
		var i int
		i, _ = str.(int)
		return float64(i)
	case int32:
		var i int32
		i, _ = str.(int32)
		return float64(i)
	case int64:
		var i int64
		i, _ = str.(int64)
		return float64(i)
	case float32:
		var i float32
		i, _ = str.(float32)
		return float64(i)
	default:
		return str.(float64)
	}
}

//转字符串
func String(str interface{}) string {
	// interface 转 string
	var key string
	if str == nil {
		return key
	}

	switch str.(type) {
	case float64:
		ft := str.(float64)
		key = strconv.FormatFloat(ft, 'f', -1, 64)
	case float32:
		ft := str.(float32)
		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
	case int:
		it := str.(int)
		key = strconv.Itoa(it)
	case uint:
		it := str.(uint)
		key = strconv.Itoa(int(it))
	case int8:
		it := str.(int8)
		key = strconv.Itoa(int(it))
	case uint8:
		it := str.(uint8)
		key = strconv.Itoa(int(it))
	case int16:
		it := str.(int16)
		key = strconv.Itoa(int(it))
	case uint16:
		it := str.(uint16)
		key = strconv.Itoa(int(it))
	case int32:
		it := str.(int32)
		key = strconv.Itoa(int(it))
	case uint32:
		it := str.(uint32)
		key = strconv.Itoa(int(it))
	case int64:
		it := str.(int64)
		key = strconv.FormatInt(it, 10)
	case uint64:
		it := str.(uint64)
		key = strconv.FormatUint(it, 10)
	case string:
		key = str.(string)
	case []byte:
		key = string(str.([]byte))
	default:
		newValue, _ := json.Marshal(str)
		key = string(newValue)
	}
	return key
}

//BuildOid 生成订单号(格式:月分2位+日期2位+随机2位+用户id4位+自增id3位+随机2位)
func BuildOid(types string, uid uint) string {
	incrId := Redis().Incr("oid:incr").Val()
	oid := types + time.Now().Format("0102") + fmt.Sprintf("%02d", time.Now().Nanosecond()/10000000) + fmt.Sprintf("%04d", uid) + fmt.Sprintf("%03d", incrId) + fmt.Sprintf("%02d", rand.Intn(time.Now().Second()+10))
	return oid
}

//Md5 md5加密
func Md5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

//GetRandom 生成随机字符串
func GetRandom(strlen int) string {
	str := "0123456789abcdefghijklmnopqrstuvwxyz"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < strlen; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

//SubString 截取字符串
func SubString(str string, begin, length int) (substr string) {
	// 将字符串的转换成[]rune
	rs := []rune(str)
	lth := len(rs)

	// 简单的越界判断
	if begin < 0 {
		begin = 0
	}
	if begin >= lth {
		begin = lth
	}
	end := begin + length
	if end > lth {
		end = lth
	}

	// 返回子串
	return string(rs[begin:end])
}

//GetRandInt 随机数字
func GetRandInt(strlen int) string {
	str := "123456789"
	bytes := []byte(str)
	result := []byte{}
	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for i := 0; i < strlen; i++ {
		result = append(result, bytes[r.Intn(len(bytes))])
	}
	return string(result)
}

//Format 格式化时间,默认2006-01-02 15:04:05
func FormatTime(formatStr ...string) string {
	var cstSh, _ = time.LoadLocation("Asia/Shanghai") //上海
	if len(formatStr) > 0 {
		return time.Now().In(cstSh).Format(formatStr[0])
	} else {
		return time.Now().In(cstSh).Format("2006-01-02 15:04:05")
	}
}

//捕获异常
func Try(tryFunc func(), catchFunc func(interface{})) {
	defer func() {
		if err := recover(); err != nil {
			catchFunc(err)
		}
	}()
	tryFunc()
}
